﻿using System.Collections.Generic;
using Game.Map;
using Game.Map.Extensions;
using Game.Objects;
using Game.Types;

namespace Game.Command.Internal
{
    public class BuildUnitScheduledCommand : ScheduledCommand
    {
        readonly IGameMap _GameMap;
        readonly VehicleType _VehicleType;
        readonly BuildUnitScheduler _Scheduler;
        readonly GameBuilding _GameBuilding;

        public BuildUnitScheduledCommand(
            GameBuilding building,
            IGameMap map,
            VehicleType vehicleType,
            BuildUnitScheduler scheduler)
            : base(2, building)
        {
            _GameMap = map;
            _VehicleType = vehicleType;
            _Scheduler = scheduler;
            _GameBuilding = building;
        }

        public override SchedulerCommand SchedulerCommand
        {
            get { return _Scheduler; }
        }

        public override string Name
        {
            get { return _VehicleType.Name; }
        }

        public override void Cancel(CommandExecutor commandExecutor)
        {
            _GameBuilding.Tank.Increase(_VehicleType.Cost);
            base.Cancel(commandExecutor);
        }

        public override void Execute()
        {
            var v = new Vehicle(_VehicleType);

            var field = FindCloseField(_GameMap);
            if (field != null)
            {
                field.VehicleX().Vehicle = v;
            }
        }

        public static GameBuilding GetBuilding(IMapField field)
        {
            var obj = field.ObjectX().GameObject;
            if (obj == null)
            {
                return null;
            }

            return obj.Building;
        }

        IMapField FindCloseField(IGameMap map)
        {
            var list = new List<IMapField>();
            foreach (var field in map.Fields)
            {
                if (GetBuilding(field) == _GameBuilding)
                {
                    list.Add(field);
                }
            }

            var possible = new List<IMapField>();
            foreach (var field in list)
            {
                var fields = MapUtil.GetAdjacentFields(map, field.Point);
                foreach (var test in fields)
                {
                    if (test.VehicleX().Vehicle == null && test.ObjectX().GameObject == null)
                    {
                        possible.Add(test);
                    }
                }
            }

            if (possible.Count == 0)
            {
                return null;
            }

            return possible[0];
        }

        internal void FireBuildUnitReady(CommandExecutor commandExecutor)
        {
            FireRunning(commandExecutor);
        }

    }
}

